<template>
  <div class="VIRTUAL_SELECT">
    <el-popover
      ref="DropDownPoppover"
      placement="bottom-start"
      :size="size"
      :width="inputWidth"
      trigger="click"
      @show="popperIsShown = true && onShow()"
      @hide="popperIsShown = false"
      popper-class="my-custom-popover"
    >
      <div
        style="padding: 3px"
        v-if="searchable && options.length > searchThreshhold"
      >
        <el-input v-model.trim="searchKeywords" @input="onSearch"></el-input>
      </div>
      <p class="el-select-dropdown__empty" v-if="filteredOptions.length === 0">
        无数据
      </p>
      <virtual-list
        v-if="popperIsShown"
        ref="VirtualList"
        style="max-height: 360px; overflow-y: auto"
        scrollable
        :data-key="'value'"
        :data-sources="filteredOptions"
        :data-component="itemComponent"
      />
    </el-popover>
    <div
      class="el-select"
      v-popover:DropDownPoppover
      ref="PopReference"
      @click.stop
    >
      <el-input v-if="!multiple" :value="optionDisplay(selectedValue)" />
      <div v-else>
        <span>
          <el-input ref="ElementInput">
            <!-- <i slot="suffix" class="el-icon-date"></i>
            <i slot="suffix" class="el-icon-date"></i> -->
          </el-input>
        </span>

        <div
          class="el-select__tags"
          style="width: 100%; overflow-y: scroll"
          :style="{ maxHeight: maxHeight }"
          ref="container"
        >
          <span>
            <el-tag
              :size="size"
              type="info"
              :key="tag"
              v-for="tag in selectedValue"
              closable
              :disable-transitions="false"
              @close="clickItem(tag)"
            >
              {{ optionDisplay(tag) }}
            </el-tag>
          </span>
        </div>
      </div>
    </div>
  </div>
</template>
  
  <script>
import elementResizeDetectorMaker from "element-resize-detector";
import { debounce } from "lodash";
import VirtualList from "vue-virtual-scroll-list";
import itemComponent from "./Item";
export default {
  name: "VirtualSelect",
  components: {
    VirtualList,
  },
  props: {
    DisplayValuesmsg: String,
    value: {
      required: true,
    },
    size: {
      type: String,
      default: () => "small",
    },
    multiple: {
      type: Boolean,
      default: () => false,
    },
    maxHeight: {
      type: String,
      default: ()=> "120px",
    },
    searchable: {
      type: Boolean,
      default: () => true,
    },
    searchThreshhold: {
      type: Number,
      default: () => 20,
    },
  },
  provide() {
    return {
      ParentVirtualSelect: () => this,
    };
  },
  data() {
    return {
      searchKeywords: "",
      itemComponent,
      originInputHeight: null,
      inputWidth: null,
      options: [],
      filteredOptions: [],
      popperIsShown: false,
    };
  },
  computed: {
    selectedValue() {
      if (this.multiple) {
        return this.value || [];
      } else {
        return this.value;
      }
    },
    optionsMap() {
      return this.options.reduce((a, b) => {
        a[b.value] = b;
        return a;
      }, {});
    },
    inputStyle() {
      if (this.inputHeight === null) {
        return {};
      }
      return {
        height: `${this.inputHeight}px`,
      };
    },
  },
  mounted() {
    let erd = elementResizeDetectorMaker();
    const el = this.$refs.container;
    if (el) {
      erd.listenTo(el, this.containerSizeChanged);
      this.originInputHeight = this.$refs.ElementInput.$el.offsetHeight;
      this.inputWidth = el.offsetWidth;
    }

    this.initTestData();
  },
  methods: {
    onShow() {
      return true;
    },
    initTestData() {
      const temp = [];
      for (let i = 0; i < 10000; i++) {
        temp.push({
          value: i,
          label: "text " + i,
        });
      }
      this.options = temp;
      this.filteredOptions = this.options;
    },
    containerSizeChanged(element) {
      const elements = [this.$refs.ElementInput];
      let height;
      if (element.offsetHeight > this.originInputHeight) {
        height = `${element.offsetHeight + 4}px`;
      } else {
        height = `${this.originInputHeight}px`;
      }
      console.log(this.$refs);
      elements.forEach((el) => {
        if (el.updatePopper) {
          el.updatePopper();
        }
        el.$refs.input.style.height = height;
      });
      const pop = this.$refs.DropDownPoppover;
      pop.updatePopper();
    },
    optionDisplay(value) {
      const option = this.optionsMap[value];
      return option ? option.label : value;
    },
    //call from chid component
    clickItem(value) {
      let emitV;
      if (this.multiple) {
        if (this.isSelected(value)) {
          emitV = this.value.filter((v) => v !== value);
        } else {
          emitV = [...this.value, value];
        }
      } else {
        emitV = value;
      }
      this.$emit("input", emitV);
      this.$emit("change", emitV);
      if (!this.multiple) {
        this.$refs.DropDownPoppover.doClose();
      }
    },
    //call from chid component
    isSelected(value) {
      if (this.multiple) {
        return this.selectedValue.includes(value);
      } else {
        return this.selectedValue === value;
      }
    },
    onSearch: debounce(function (keywords) {
      this.filteredOptions = this.options.filter((item) =>
        item.label.includes(keywords)
      );
      this.$refs.VirtualList.scrollToIndex(0);
    }, 300),
    focus() {
      // this.$refs.ElementInput.focus();

      const pop = this.$refs.DropDownPoppover;

      // let reference = pop.reference || pop.$refs.reference;
      // if (!reference && pop.$slots.reference && pop.$slots.reference[0]) {
      //   reference = pop.referenceElm = pop.$slots.reference[0].elm;
      // }
      // reference.click();
      pop.doShow();
      // this.$nextTick(() => {
      //   console.log(pop);
      // })
      // const popReference = this.$refs.PopReference;
      // debugger
      // popReference.click();
    },
  },
};
</script>
  
  <!-- Add "scoped" attribute to limit CSS to this component only -->
  <style scoped>
</style>
  <style>
.my-custom-popover {
  padding: 0px !important;
  /* padding-right: 0px !important; */
}
</style>
  